# 220130 627
'''
NumPy(Numerical Python) 是 Python 语言的一个扩展程序库，
支持大量的维度数组与矩阵运算，此外也针对数组运算提供大量的数学函数库。

前身 Numeric 最早是由 Jim Hugunin 与其它协作者共同开发
2005 年，Travis Oliphant 
NumPy 为开放源代码并且由许多协作者共同维护开发。

NumPy 是一个运行速度非常快的数学库，主要用于数组计算
[
	一个强大的N维数组对象 ndarray
	广播功能函数
	整合 C/C++/Fortran 代码的工具
	线性代数、傅里叶变换、随机数生成等功能
}

通常与 SciPy（Scientific Python）和 Matplotlib（绘图库）一起使用
用于替代 MatLab，是一个强大的科学计算环境
通过 Python 学习数据科学或者机器学习

SciPy 是一个开源的 Python 算法库和数学工具包。
Matplotlib 是 Python 编程语言及其数值数学扩展包 NumPy 的可视化操作界面。
'''

# numpy                1.18.4

# 测试安装是否成功
from numpy import *

eye4 = eye(4)
print(eye4)

# Ndarray 对象
# N 维数组对象 ndarray，它是一系列同类型数据的集合
# 以 0 下标为开始进行集合中元素的索引
# 数据类型或 dtype
# 表示数组形状（shape）的元组
# 跨度元组（stride）
# 跨度可以是负数

# 创建一个 ndarray 只需调用 NumPy 的 array 函数即可：
# numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)

import numpy as np

a = np.array([1,2,3])
print(a)

# 多位数组
a = np.array([[1,2],[3,4]])
print(a)

# 最小维度
a = np.array([1,2,3,4,5], ndmin=3) # [[[1 2 3 4 5]]]
print(a)

# dtype 参数
a = np.array([1,2,3], dtype=complex)
print(a) # [1.+0.j 2.+0.j 3.+0.j]

# ndarray 对象由计算机内存的连续一维部分组成，并结合索引模式，
# 将每个元素映射到内存块中的一个位置。
# 内存块以行顺序(C样式)或列顺序(FORTRAN或MatLab风格，
# 即前述的F样式)来保存元素。

print('end.1')

# 数据类型
# numpy 支持的数据类型比 Python 内置的类型要多很多
# bool_ int_ intc intp int8 int16 int32 int64 uint...
# float_ 16/32/64 complex_ 64/128
# numpy 的数值类型实际上是 dtype 对象的实例

# 数据类型对象 (dtype)
# 字节顺序是通过对数据类型预先设定 < 或 > 来决定的。
# < 意味着小端法
# > 意味着大端法
# dtype 对象是使用以下语法构造的：
# numpy.dtype(object, align, copy)

dt82 = np.dtype(np.int32)
print('dt82=', dt82)

# # int8, int16, int32, int64 四种数据类型
# 可以使用字符串 'i1', 'i2','i4','i8' 代替

dt88 = np.dtype('i8')
print('dt88=', dt88)

dt91 = np.dtype('<i4')
print('dt91=', dt91)

# 结构化数据类型的使用
dt95 = np.dtype([('age', np.int8)])
print('dt95=', dt95)

# 将数据类型应用于 ndarray 对象
arr99 = np.array([(10,),(20,),(30,)], dtype=dt95)
print('arr99=', arr99) # [(10,) (20,) (30,)]

# 类型字段名可以用于存取实际的 age 列
print(arr99['age']) # [10 20 30]

# 定义一个结构化数据类型 student
student = np.dtype([('name', 'S20'), ('age', 'i1'), ('marks', 'f4')])
print('student=', student)

arr109 = np.array([('abc', 21, 50),('xyz', 18, 75)], dtype=student)
print('arr109=', arr109) # [(b'abc', 21, 50.) (b'xyz', 18, 75.)]

# 每个内建类型都有一个唯一定义它的字符代码
# b i u f c-complex
# m M O S,a U-Unicode V-void
# 有什么用？

print('end.2')

# 数组属性
# NumPy 数组的维数称为秩（rank），秩就是轴的数量，即数组的维度
# 一维数组就是 NumPy 中的轴（axis）
# 第一个轴相当于是底层数组，第二个轴是底层数组里的数组
# 轴的数量——秩，就是数组的维数
# 可以声明 axis。axis=0，表示沿着第 0 轴进行操作，即对每一列进行操作；
# axis=1，表示沿着第1轴进行操作，即对每一行进行操作。

# rank dimensions axis

# 比较重要 ndarray 对象属性有：
# ndim shape size dtype itemsize flags real imag data

# 使用上面的 arr109
print('arr109=', arr109.ndim, arr109.shape, arr109.size, arr109.itemsize) # 1 (2,) 2 25
print('flags=', arr109.flags, '\nreal=', arr109.real, '\nimag=', arr109.imag)
print(arr109.data) # <memory at 0x0000023F22A62048>

# ndim
arr137 = np.arange(24)
print('arr137=', arr137)

print(arr137.ndim) # 1

# 调整其大小
b143 = arr137.reshape(2,4,3)
print('b143=', b143)
print(b143.ndim) # 3

# shape 数组的维度，返回一个元组

# reshape 函数来调整数组大小
# ndarray.reshape 通常返回的是非拷贝副本，即改变返回后数组的元素，
# 原数组对应元素的值也会改变。

a152 = np.array([[1,2,3], [4,5,6]])
print('a152=', a152)
b154 = a152.reshape(3,2)
print('b154=', b154)
print('a152 2=', a152) # 未改变

# itemsize 以字节的形式返回数组中[每一个元素的大小]

# flags  对象的内存信息

print('end.3')
